package com.leyou.seckill.service;

import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.seckill.dto.SecKillOrderDTO;
import com.leyou.seckill.dto.SeckillPolicyDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class SecKillRedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;


    private String secKillInfo_PRE = "ly:seckill:goods:";

    private String secKillList_PRE = "ly:seckill:list:";
    /**
     * 把秒杀商品信息放入redis中
     */
    public void putSeckillPolicyToRedis(SeckillPolicyDTO seckillPolicyDTO){

//        商品信息放入redis.选择使用string,如果想要设置有效期，要根据秒杀的结束时间
        String redisKey  =  secKillInfo_PRE + seckillPolicyDTO.getId();
        redisTemplate.opsForValue().set(redisKey, JsonUtils.toString(seckillPolicyDTO));
//        生成秒杀的队列，秒杀有多少库存 队列中就有多少个 元素
//        获取秒杀的库存
        Integer stockCount = seckillPolicyDTO.getStockCount();
        String listKey = secKillList_PRE + seckillPolicyDTO.getId();
//        生成队列的元素
        for(int i=0;i<stockCount;i++){
            redisTemplate.opsForList().leftPush(listKey,i+"");
        }
    }

    public void removeSecKillRedisInfo(Long id){
//        删除秒杀商品信息
        String redisKey  =  secKillInfo_PRE + id;
        redisTemplate.delete(redisKey);

//        删除秒杀队列信息
        String listKey = secKillList_PRE + id;
        redisTemplate.delete(listKey);
    }

    /**
     * 判断当前时间，秒杀是否正在进行
     * @param seckillId
     */
    public void isValiteTime(Long seckillId) {
//        秒杀商品信息的rediskey
        String redisKey  =  secKillInfo_PRE + seckillId;
//        从redis中获取商品信息
        String secKillJson = redisTemplate.opsForValue().get(redisKey);
//        转对象
        SeckillPolicyDTO seckillPolicyDTO = JsonUtils.toBean(secKillJson, SeckillPolicyDTO.class);
//        获取开始时间
        long beginTime = seckillPolicyDTO.getBeginTime().getTime();
//        获取结束时间
        long endTime = seckillPolicyDTO.getEndTime().getTime();
//        当前时间
        long now = System.currentTimeMillis();
//        判断当前秒杀是否在进行
        if(now < beginTime){
            throw new LyException(ExceptionEnum.SECKILL_NOT_BEGIN);
        }
        if(now > endTime){
            throw new LyException(ExceptionEnum.SECKILL_IS_END);
        }
    }

    /**
     * 从redis队列中进行秒杀操作
     * @param seckillId
     * @return true -秒杀成功  false -秒杀没成功
     */
    public boolean hasGoods(Long seckillId) {
        String listKey = secKillList_PRE + seckillId;
//        从redis队列中弹出数据
        String code = redisTemplate.opsForList().leftPop(listKey);
        if(StringUtils.isBlank(code)){
//            队列中已经没有数据
            return false;
        }
        return true;
    }
}
